<?php
/**
 * Memcached 行数据缓存
 * 
 * 限制条件：
 * 1、每张表必须有主键。
 * 2、依赖主键查询
 * 
 * 缓存以用户为中心, 分模块存储。
 * 
 * 需要缓存的数据主要分两部分:
 * 第一部分是数据缓存A, 在A中KEY是数据库具体模块行数据的ID，Value是模块数据库ID对应的行数据。
 * 第二部分是以用户为单位的模块数据ID列表缓存B, 在B中KEY是各模块对应下的Uid, Value是该Uid对应的该模块下所有数据ID组成的列表。
 * 
 * @author fanzhanao <fanzhanao@178.com>
 * @version $Id: MemcacheRow.php 4766 2010-04-09 06:23:04Z fanzhanao $
 * @package MemcacheRow
 */
abstract class MemcacheRow
{
	/**
	 * 缓存KEY前缀
	 *
	 */
    const CACHE_PREFIX 	 = 'manhua';
    
    /**
     * 缓存生存期
     *
     */
    const CACHE_LEFTTIME = 600;
    
	/**
	 * 构造函数
	 *
	 */
    protected function __construct() {}
	
   /**
    * 获取多个key的缓存数据
    * 
    * 该方法接受的参数为模块内唯一id和缓存key的对应关系如：
    * $hashKey = array(
    * 		12 => 'nga_friends_12',
    * 		13 => 'nga_friends_13',
    * 		14 => 'nga_friends_14'
    * )
    * 
    * 如果缓存全部命中$hits返回缓存key和缓存数据的对应数组, $misses返回array()。
    * 
    * 如果缓存部分命中$hits返回缓存key和缓存数据的对应数组, $misses返回缓存key和模块内id的对应关系数组如:
    * $misses = array(
    * 		'nga_friends_13' => 13,
    * 		'nga_friends_14' => 14
    * );
    * 
    *
    * @param array $hashKey	id和缓存key对应关系数组
    * @return array			命中和未命中缓存数组
    */
    protected static function getMulti($hashKey)
    {
    	//初始化命中和未命中数组
    	$hits 	 = $misses = array();
    	
    	$hashKey = (array) $hashKey;
       
        $keys 	 = array_values($hashKey);
        
        //命中的缓存
        $hits 	 = self::get($keys);
		
        //key和id的对应关系数组
        $flipKey = array_flip($hashKey);
		
		if (!$hits) {
			return array($misses, $flipKey);
		}

        //获取的键值对缺少
        if ( count($hits) != count($keys) ) {
        	//获取未命中的缓存id
            $misses = array_diff_key($flipKey, $hits);
        }
        
        return array($hits, $misses);
    }
    
    /**
     * 获取单个key的缓存数据
     * 
     * 1. 如果参数是string 出错或缓存不存在会返回false
     * 2. 如果参数是数组，出错返回false, 缓存不存在会返回array();
     *
     * @param string $key	缓存key
     * @return mixed		缓存数据或错误标示
     */
    protected static function get($key)
    {
    	return Mem::getInstance()->get($key);
    }
    
    /**
     * 设置多个key的缓存数据
     *
     * @param array $data	结构为key和data的对应数组
     */
    protected static function setMulti($data, $leftTime = self::CACHE_LEFTTIME)
    {
    	foreach ((array) $data as $key => $val) {
    		self::set($key, $val, $leftTime);
    	}
    }
    
  	/**
  	 * 设置单个key的缓存数据
  	 * 
  	 * @param string $key	缓存key
  	 * @param array $data	缓存数据
  	 * @param int $leftTime	缓存时间
  	 * @return bool			缓存成功 返回true 失败返回false
  	 */
    protected static function set($key, $data, $leftTime = self::CACHE_LEFTTIME)
    {
        return Mem::getInstance()->set($key, $data, $leftTime);
    }
    
  	/**
  	 * 删除指定key的缓存数据
  	 *
  	 * @param string $key 缓存key
  	 * @return bool	删除缓存成功 返回true 失败返回false
  	 */
    protected static function remove($key)
    {
        return Mem::getInstance()->remove($key);
    }
	
	/**
	 * 创建一个key
	 *
	 * @param array $params		缓存key生成参数
	 * @param string|null $module	模块名
	 * @return str				缓存key
	 */
	protected static function genkey($params, $module = null)
	{
		if (null === $module) {
			return strtolower(self::CACHE_PREFIX . '_' . implode('_', $params));
		} else {
			return strtolower(self::CACHE_PREFIX . '_' . $module . '_' . implode('_', $params));
		}
	}
}
